#include "stdafx.h"
#include "Serializer\StandardSerializer.h"
#include <crtdbg.h>

using namespace persist;

StandardSerializer::StandardSerializer()
{
	mode = READ;
}

StandardSerializer::StandardSerializer(const std::string& _name)
{
	name = _name;
	mode = READ;
}
StandardSerializer::StandardSerializer(const std::string& _name, Persistor::Mode m)
{
	name = _name;
	mode = m;

}

StandardSerializer::~StandardSerializer()
{

}

void StandardSerializer::persist(Persistent*& _persistent)
{
	if (mode == READ)
	{
		Record record;
		*this << record;
		if (record.id==Identifier(""))
		{
//found a zero object
			_persistent=0;
			return;

		}
		if (record.persistorName=="")
		{
			record.persistorName=name;
		}
//wanna make sure only one instance of a class under a given name gets created
		Records::iterator it=records.find(record);
		if (it!=records.end())
		{
			_persistent=it->second;
		}
		else
		{
			
			Factory* fac=getFactory();
			_ASSERTE(fac);
			_persistent=(Persistent*)fac->create(record.id);
			_persistent->setName(record.persistentName);
			if (!_persistent->getPersistor()) _persistent->setPersistor(this);
			persistents[_persistent]=record;
			records[record]=_persistent;
//find somebody who knows how to load this thing
			if (_persistent->getPersistor()->getName()!=record.persistorName)
			{
				_ASSERTE(false);
				/*
				Persistor* persistor=globalPersistorsManager->getPersistor(record.persistorName,READ);
				_ASSERTE(persistor);
				_persistent->setPersistor(persistor);
				*/
			}
			_persistent->load(); //resolves to:
								 //persistor->load(_persistent)
								 //     persistor->fill(persistent)
								 //          persistent->serialize(persistor)
			                     //               persistor->operator<<(persistent)
								 //                   persistor->serialize(data)
			
		}
	}
	else
	{
		if (_persistent == 0)
        {
//in case some idiot really needed to flush a zero object
            Record record;
            record.id = Identifier("");

            *this << record;
            return;
        }


		Persistents::iterator it = persistents.find(_persistent);
//wanna flush an instance only once
		if (it!=persistents.end())
		{
			*this << it->second;
		}
		else
		{
			if (_persistent->getPersistor() == 0)
            {
                _persistent->setPersistor(this);
            }
            std::string persistentName = _persistent->getName();
            if (persistentName.empty())
            {
//don't wanna save with empty name, so generate one
                persistentName = _persistent->getPersistor()->allocate(_persistent->getId());
                _persistent->setName(persistentName);
            }
            Record record(_persistent->getId(), 
                _persistent->getPersistor()->getName(),
                _persistent->getName());
            if (_persistent->getPersistor()->getName() == name)
            {
                record.persistorName = "";
            }
            persistents[_persistent] = record;
            records[record] = _persistent;
            *this << record;
            _persistent->save();
		}

	}

}

